﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace BasicLight.Unleashed
{
    public class ImagingAsync
    {
        public ImagingAsync()
        {
            _targets = new Dictionary<string, string>();
            Local = null;
        }

        public DependencyObject Holder { private get; set; }

        public string Local { get; set; }

        /// <summary>
        /// 请求项
        /// </summary>
        private Dictionary<string, string> _targets { get; set; }

        /// <summary>
        /// 开始
        /// </summary>
        public void Begin()
        {
            _lock = false;

            if (String.IsNullOrEmpty(Local))
            {
                RequestAsync();
            }
            else
            {
                RequestLocal();
            }
        }

        private async void RequestLocal()
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            StorageFolder storageFolder = null;
            bool folderNotFound = false;
            try
            {
                storageFolder = await localFolder.GetFolderAsync(this.Local);
            }
            catch (FileNotFoundException)
            {
                folderNotFound = true;
            }
            if (folderNotFound) return;

            Image target = null;
            BitmapSource source = null;
            StorageFile imageFile = null;
            IRandomAccessStream imageSource = null;

            foreach (KeyValuePair<string, string> item in _targets)
            {
                target = ElementExpress.FindChild<Image>(this.Holder, item.Key);
                if (target != null)
                {
                    try
                    {
                        imageFile = await storageFolder.GetFileAsync(item.Value.Safely() + ".txt");
                        imageSource = await imageFile.OpenAsync(FileAccessMode.Read);

                        source = new BitmapImage();
                        source.SetSource(imageSource);
                        target.Source = source;
                    }
                    catch (FileNotFoundException)
                    {
                    }
                    finally
                    {
                        source = null;
                        imageSource.Dispose();
                    }
                }
            }

            _targets.Clear();
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="name"></param>
        /// <param name="url"></param>
        public void Queue(string name, string url)
        {
            if (false == _targets.ContainsKey(name))
            {
                _targets.Add(name, url);
            }
        }

        private bool _lock = false;
        private HttpClient _client;

        private async void RequestAsync()
        {
            if (_targets.Count == 0 || _lock) return;

            foreach (KeyValuePair<string, string> item in _targets)
            {
                _client = new HttpClient();
                var response = await _client.GetAsync(item.Value);
                if (response.IsSuccessStatusCode)
                {
                    Image target = ElementExpress.FindChild<Image>(this.Holder, item.Key);
                    Stream imageStream = null;
                    InMemoryRandomAccessStream imageSource = null;
                    DataWriter dataWriter = null;
                    BitmapSource source = null;
                    IOutputStream outputStream = null;

                    if (target != null)
                    {
                        try
                        {
                            imageStream = await response.Content.ReadAsStreamAsync();
                            byte[] bytes = imageStream.ToBytes();
                            imageSource = new InMemoryRandomAccessStream();
                            outputStream = imageSource.GetOutputStreamAt(0);
                            dataWriter = new DataWriter(outputStream);
                            dataWriter.WriteBytes(bytes);
                            await dataWriter.StoreAsync();

                            source = new BitmapImage();
                            source.SetSource(imageSource);
                            target.Source = source;
                        }
                        catch
                        {
                        }
                        finally
                        {
                            source = null;
                            _client.Dispose();
                            dataWriter.Dispose();
                            imageStream.Dispose();
                            imageSource.Dispose();
                            outputStream.Dispose();
                        }
                    }
                }

                _targets.Remove(item.Key);
                RequestAsync();

                break;
            }
        }

        /// <summary>
        /// 停止当前异步请求，并清空请求项。
        /// </summary>
        public void Cancel()
        {
            _lock = true;
            _targets.Clear();
            _lock = false;
        }

        /// <summary>
        /// 停止当前异步请求，但保留请求项。
        /// </summary>
        public void Pause()
        {
            _lock = true;
        }
    }
}
